import pug from 'pug'
import path from 'path'
import fs from 'fs'

import fastify from 'fastify'
import fastifyBlipp from 'fastify-blipp'
import pointOfView from 'point-of-view'
import fastifyStatic from 'fastify-static'
import fastifyCompress from 'fastify-compress'
import proxy from 'fastify-http-proxy'
import { bootstrap as controller } from 'fastify-decorators'
import { Server as HttpServer, IncomingMessage, ServerResponse } from 'http'
import { Server as HttpsServer } from 'https'
import { ConfigService } from './services/config.service'
import { Container, Scope } from 'typescript-ioc'
import { Application } from './application'

// 获取基础配置
Container.bind(ConfigService)
  .to(ConfigService)
  .scope(Scope.Singleton)
const configService = Container.get(ConfigService)

const HTTPS = configService.get('HTTPS')
const PROXY_ADDRESS = configService.get('PROXY_ADDRESS')

// 关闭https证书认证检测(用于访问自签名证书地址)
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'

// https服务配置-用于本地调试
const httpsConfig = {
  allowHTTP1: true, // fallback support for HTTP1
  key: fs.readFileSync(path.join(__dirname, '..', 'cert', 'localhost.key')),
  cert: fs.readFileSync(path.join(__dirname, '..', 'cert', 'localhost.crt'))
}

// 创建服务实例
const server: fastify.FastifyInstance<HttpServer | HttpsServer, IncomingMessage, ServerResponse> = fastify({
  // 允许URL地址`/`结尾
  ignoreTrailingSlash: true,
  // 插件初始化超时限制
  pluginTimeout: 30000,
  // 开启日志打印
  logger: {
    prettyPrint: true,
    level: 'trace'
  },
  // https设置
  https: HTTPS ? httpsConfig : undefined
})

// 相关服务插件
server
  // 注册路由回显插件
  .register(fastifyBlipp)
  // 注册ViewEngine插件
  .register(pointOfView, { engine: { pug } })
  //  注册静态文件服务插件
  .register(fastifyStatic, {
    root: path.join(__dirname, '..', 'public'),
    prefix: '/'
  })
  // 注册控制器发现插件
  .register(controller, {
    controllersDirectory: path.join(__dirname, `controllers`),
    controllersMask: /\.controller\.(ts|js)$/
  })
  // 注册g-zip插件
  .register(fastifyCompress, { global: true })
  //  注册API代理插件
  .register(proxy, {
    upstream: PROXY_ADDRESS,
    prefix: '/api',
    rewritePrefix: '',
    http2: false
  })
  .ready()
  // 初始化服务
  .then(Application.initialize)
  // 启动服务
  .then(Application.bootstrap)
